package com.smzd.framework.sso;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.catalina.util.Base64;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;

import com.qq.connect.api.OpenID;
import com.qq.connect.api.qzone.UserInfo;
import com.qq.connect.javabeans.AccessToken;
import com.qq.connect.javabeans.Avatar;
import com.qq.connect.javabeans.qzone.UserInfoBean;
import com.qq.connect.oauth.Oauth;
import com.smzd.framework.security.domain.Authority;
import com.smzd.framework.system.business.UserBindService;
import com.smzd.framework.system.business.UserService;
import com.smzd.framework.system.domain.Group;
import com.smzd.framework.system.domain.Meeting;
import com.smzd.framework.system.domain.Role;
import com.smzd.framework.system.domain.User;
import com.smzd.framework.system.domain.UserBind;
import com.smzd.utils.httpclient.Client;
import com.smzd.utils.httpclient.Request;
import com.smzd.utils.httpclient.Response;

@Deprecated
public class XtwlAuthenticationProcessingFilter extends BaseXtwlAuthenticationProcessingFilter {

    private String localUrl = "http://localhost:8080/xin2core";

    private String xtwlUrl = "http://localhost:8080/UserCenter";
    private String xtwlAppKey = "35c813f5-dee1-467f-9b85-8d263a0b06f1";
    private String xtwlAppSecret = "ca8f62f6-35e8-4100-84ff-5a52fc5816f0";

    // private String qqUrl = "";
    // private String qqAppKey = "";
    // private String qqAppSecret = "";
    //
    // private String wbUrl = "";
    // private String wbAppKey = "";
    // private String wbAppSecret = "";

    @Autowired
    private UserBindService userBindService;
    @Autowired
    private UserService userService;

    private Client CLIENT_INST = new Client();

    private final static List<GrantedAuthority> authorities = Arrays.asList((GrantedAuthority) new Authority(
            "ROLE_USER"));

    protected XtwlAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
        super(defaultFilterProcessesUrl);
    }

    public XtwlAuthenticationProcessingFilter() {
        this("/sso/xtwl_getticket");
    }

    private User extractUserFromJson(String json) throws JSONException {
        System.out.println("从远端获取的登录用户信息：" + json);
        User user = new User();
        JSONObject obj = new JSONObject(json);
        // id
        user.setId(obj.has("id") ? obj.getInt("id") : null);
        // name
        user.setName(obj.has("name") ? obj.getString("name") : "Anonymous");
        // meeting
        JSONObject meetingJson = obj.has("scope") ? obj.getJSONObject("scope") : null;
        if (meetingJson != null) {
            Meeting meeting = new Meeting();
            int meetingId = meetingJson.has("id") ? obj.getInt("id") : 0;
            if (meetingId > 0) {
                meeting.setId(meetingId);
            }
            String meetingName = meetingJson.getString("name");
            meeting.setName(meetingName);
            user.setOwner(meeting);
        }
        // roles
        JSONArray rolesJsonArr = obj.has("roles") ? obj.getJSONArray("roles") : null;
        if (rolesJsonArr != null && rolesJsonArr.length() > 0) {
            List<Role> roles = new ArrayList<Role>();
            for (int i = 0; i < rolesJsonArr.length(); i++) {
                JSONArray roleJsonArr = rolesJsonArr.getJSONArray(i);
                Role role = new Role();
                role.setId(roleJsonArr.getInt(0));
                role.setName(roleJsonArr.getString(1));
                role.setValue(roleJsonArr.getString(1));
                role.setDescription(roleJsonArr.getString(2));
                roles.add(role);
            }
            user.setRoles(roles);
        }
        // groups
        JSONArray groupsJsonArr = obj.has("groups") ? obj.getJSONArray("groups") : null;
        if (groupsJsonArr != null && groupsJsonArr.length() > 0) {
            List<Group> groups = new ArrayList<Group>();
            for (int i = 0; i < groupsJsonArr.length(); i++) {
                JSONArray groupJsonArr = groupsJsonArr.getJSONArray(i);
                Group group = new Group();
                group.setId(groupJsonArr.getInt(0));
                group.setName(groupJsonArr.getString(1));
                groups.add(group);
            }
            user.setGroups(groups);
        }

        System.out.println("----当前登录用户：" + user);
        return user;
    }

    protected Authentication getAuthentication(int type, Object userInfo, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        User remoteUser = null;
        if (type == UserBind.AUTH_TYPE_XTWL_CAS || type == UserBind.AUTH_TYPE_XTWL_OAUTH) {
            remoteUser = extractUserFromJson((String) userInfo);
            remoteUser.setPassword(String.valueOf(remoteUser.getId()));
            // 试图获取本地绑定的用户
        } else if (type == UserBind.AUTH_TYPE_SINA_WEIBO) {
            weibo4j.model.User weiboUser = (weibo4j.model.User) userInfo;
            String userDomain = weiboUser.getUserDomain(); // 用户登录名
            String screenName = weiboUser.getScreenName(); // 用户昵称
            // String avatar = weiboUser.getAvatarLarge(); // 用户头像
            String id = weiboUser.getId();// openid
            remoteUser = new User();
            remoteUser.setName(screenName);
            remoteUser.setDescription(userDomain);
            remoteUser.setPassword(id);
        } else if (type == UserBind.AUTH_TYPE_QQ_CONNECT) {
            remoteUser = (User) userInfo;
        }
        if (remoteUser == null) {
            throw new Exception("远程登录发生错误！");
        }
        UserBind userBind = userBindService.getUserBindByOpenid(remoteUser.getPassword());// password里面存放的是openid
        if (userBind == null) {
            HttpSession session = request.getSession();
            DefaultSavedRequest dsr = (DefaultSavedRequest) session.getAttribute("_SPRING_SECURITY_SAVED_REQUEST_");// 自定义key值
            if (dsr == null) {
                dsr = (DefaultSavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST");// springsecurity的标准key值
                if (dsr != null) {
                    session.setAttribute("_SPRING_SECURITY_SAVED_REQUEST_", dsr);
                }
            }
            session.setAttribute("_remote_user_", remoteUser);
            session.setAttribute("_remote_user_type_", type);

            Meeting meeting = new Meeting();
            meeting.setId(1);
            remoteUser.setOwner(meeting);

            userService.insert(remoteUser);

            userBind = new UserBind();
            userBind.setOwner(remoteUser);
            userBind.setName(remoteUser.getName());
            userBind.setOpenid(String.valueOf(remoteUser.getId()));
            userBind.setType(UserBind.AUTH_TYPE_XTWL_OAUTH);
            userBindService.insert(userBind);
            remoteUser.setAuthorities(authorities);
            return new UsernamePasswordAuthenticationToken(remoteUser, "PASS", remoteUser.getAuthorities());
        } else {
            User localUser = userService.getItemById(userBind.getOwner().getId());
            if (localUser != null) {
                localUser.setAuthorities(authorities);
                return new UsernamePasswordAuthenticationToken(localUser, "PASS", localUser.getAuthorities());
            }
        }
        return null;
    }

    protected Object getUserInfoByAccessToken(int type, Object accessToken, HttpServletRequest request)
            throws Exception {
        Object result = null;
        if (type == UserBind.AUTH_TYPE_XTWL_CAS) {// xtwl_cas此时已经返回的就是用户的信息，无需再访问
            result = accessToken;
        } else if (type == UserBind.AUTH_TYPE_XTWL_OAUTH) {// xtwl_oauth此时返回的是access_token完整信息
            JSONObject obj = new JSONObject((String) accessToken);
            String accessTokenStr = obj.getString("access_token");
            System.out.println("-->access_token=" + accessTokenStr);
            Request req = CLIENT_INST.GET(getServerPath(xtwlUrl) + "/sso/userinfo.action")
                    .addHeader("Accept", "application/octet-stream, application/json, */*")
                    .addHeader("authorization", "Bearer " + accessTokenStr);
            Response res = req.execute();
            String json = res.getResponseContent().toString();
            return json;

        } else if (type == UserBind.AUTH_TYPE_SINA_WEIBO) {
            weibo4j.http.AccessToken accessTokeObj = (weibo4j.http.AccessToken) accessToken;
            String uid = accessTokeObj.getUserUid();
            weibo4j.Users users = new weibo4j.Users();
            users.client.setToken(accessTokeObj.getAccessToken());
            weibo4j.model.User user = users.showUserById(uid);
            result = user;
        } else if (type == UserBind.AUTH_TYPE_QQ_CONNECT) {
            AccessToken accessTokenApi = (AccessToken) accessToken;
            String access_token = accessTokenApi.getAccessToken();
            System.out.println("access_token=" + access_token);
            OpenID openIdApi = new OpenID(access_token);
            System.out.println("openIdApi=" + access_token);
            String openId = openIdApi.getUserOpenID();
            System.out.println("openId=" + openId);
            UserInfo userInfoApi = new UserInfo(access_token, openId);
            UserInfoBean userInfoBean = userInfoApi.getUserInfo();
            String nickName = userInfoBean.getNickname();
            String gender = userInfoBean.getGender();
            Avatar avatar = userInfoBean.getAvatar();
            String url_100 = avatar.getAvatarURL100();
            String url_50 = avatar.getAvatarURL50();
            String url_30 = avatar.getAvatarURL30();
            StringBuffer sb = new StringBuffer();
            sb.append("access_token: ").append(access_token).append("; gender: ").append(gender).append("; url_100: ")
                    .append(url_100).append("; url_50: ").append(url_50).append("; url_30: ").append(url_30);
            User user = new User();
            user.setName(nickName);
            user.setPassword(openId);
            user.setGender(0);
            user.setDescription(sb.toString());
            result = user;
        }
        return result;
    }

    protected String getServerPath(String url) {
        if (url == null) {
            throw new RuntimeException("");
        }
        if (url.endsWith("/")) {
            return url.substring(0, url.length() - 1);
        }
        return url;
    }

    protected Object getAccessToken(int type, String code, HttpServletRequest request) throws Exception {
        if (type == UserBind.AUTH_TYPE_XTWL_CAS) {
            throw new Exception("还未调试CAS的统一登录");
        } else if (type == UserBind.AUTH_TYPE_XTWL_OAUTH) {
            String url = getServerPath(xtwlUrl) + "/oauth/token";
            Request req = CLIENT_INST.POST(url).addParameter("grant_type", "authorization_code")
                    .addParameter("redirect_uri", getServerPath(localUrl) + "/sso/xtwl_getticket?_type=1")
                    .addParameter("code", code).addHeader("Accept", "application/json")
                    .addHeader("authorization", "Basic " + encodeAuthorization(xtwlAppKey, xtwlAppSecret));
            System.out.println("getAccessToken: " + req.getHttpRequest().getURI().toASCIIString());
            Response res = req.execute();
            String json = res.getResponseContent().toString();
            System.out.println("----获取到的json字符串为：" + json);
            return json;
        } else if (type == UserBind.AUTH_TYPE_SINA_WEIBO) {
            weibo4j.Oauth oauth = new weibo4j.Oauth();
            weibo4j.http.AccessToken accessToken = oauth.getAccessTokenByCode(code);
            return accessToken;
        } else if (type == UserBind.AUTH_TYPE_QQ_CONNECT) {
            String queryString = request.getQueryString();
            AccessToken accessTokenApi = (new Oauth()).getAccessTokenByQueryString(queryString, "3");
            System.out.println("accessTokenApi=" + accessTokenApi);
            System.out.println("accessTokenApi.access_token=" + accessTokenApi.getAccessToken());
            System.out.println("accessTokenApi.expire_in=" + accessTokenApi.getExpireIn());
            return accessTokenApi;
        }
        throw new Exception("未收支持的认证类型！_type=" + type);
    }

    private String encodeAuthorization(String id, String secret) {
        String base = id + ":" + secret;
        return Base64.encode(base.getBytes());
    }

    public String getLocalUrl() {
        return localUrl;
    }

    public void setLocalUrl(String localUrl) {
        this.localUrl = localUrl;
    }

    public String getXtwlUrl() {
        return xtwlUrl;
    }

    public void setXtwlUrl(String xtwlUrl) {
        this.xtwlUrl = xtwlUrl;
    }

    public String getXtwlAppKey() {
        return xtwlAppKey;
    }

    public void setXtwlAppKey(String xtwlAppKey) {
        this.xtwlAppKey = xtwlAppKey;
    }

    public String getXtwlAppSecret() {
        return xtwlAppSecret;
    }

    public void setXtwlAppSecret(String xtwlAppSecret) {
        this.xtwlAppSecret = xtwlAppSecret;
    }
}
